package sg.edu.nus.dashboard.util
{
	import mx.collections.ArrayCollection;
	import mx.controls.Alert;
	import mx.formatters.DateFormatter;
	import mx.utils.ObjectUtil;
	
	import sg.edu.nus.dashboard.main.model.AppModelLocator;
	import sg.edu.nus.dashboard.vo.BaselineVo;
	import sg.edu.nus.dashboard.vo.ParaStatVo;
	import sg.edu.nus.dashboard.vo.PieStatVo;

	public class StatUtil
	{
		public function StatUtil()
		{
			
		}
		
		public static function getFloor15Min(date:Date):Date {
			
			var min:Number;
			
			if(0 <= date.getMinutes() && 15 > date.getMinutes())
				min = 0;
			else if (15 <= date.getMinutes() && 30 > date.getMinutes())
				min = 15;
			else if (30 <= date.getMinutes() && 45 > date.getMinutes())
				min = 30;
			else
				min = 45;
			
			return new Date(date.getFullYear(), date.getMonth(), date.getDate(),
				date.getHours(), min);
		}
		
		// get current health ratio
		public static function getCurrentHealthRatio():void {
			
			var model:AppModelLocator = AppModelLocator.getInstance();
			
			var pvo:ParaStatVo = ParaStatVo(model.stat.statRawArr.getItemAt(
					model.stat.statRawArr.length - 1, 0));
			
			model.stat.currentRatioStr = pvo.ratio.toFixed(2).toString()+"%";
			
			var notSoHealthy:Number;
			var needAttention:Number;
			
			// get baseline by selected parameter name
			for each(var vo:BaselineVo in model.baseline.baselineItemArr) {
				if(vo.paraName == model.stat.selectedPara) {
					notSoHealthy = vo.notSoHealthy;
					needAttention = vo.needAttention;
				}
			}
			
			// change image
			if(pvo.ratio <= notSoHealthy) {
				model.stat.imageURL = "assets/icon/healthy.gif";
			} else if (pvo.ratio > notSoHealthy && pvo.ratio <= needAttention) {
				model.stat.imageURL = "assets/icon/notsohealthy.png";
			} else {
				model.stat.imageURL = "assets/icon/needattention.png";
			}
		}
		
		// convert statRawArr to statShowArr
		public static function filterStat():void {
			
			var model:AppModelLocator = AppModelLocator.getInstance();
			
			var dateFormatter:DateFormatter = new DateFormatter();
			var hourFormatter:DateFormatter = new DateFormatter();
			var minFormatter:DateFormatter = new DateFormatter();
			
			dateFormatter.formatString = "DD/MM/YYYY";
			hourFormatter.formatString = "DD/MM HH:NN";
			minFormatter.formatString = "HH:NN";
			
			var day:Number = 1000*60*60*24;
			var hour:Number = 1000*60*60;
			var fifteenMin:Number = 1000*60*15;
			
			var tempArr:ArrayCollection = new ArrayCollection();
			var tempStatVo:ParaStatVo;
			
			if(model.stat.selectedLevel == 0) // level 1 - day interval
			{ 
				// construct StatShowArr
				var nextDate:Date;
				var i:int = 0;
				var total:Number = 0;
				var count:int = 0;
				
				var fromDate:Date = new Date(model.stat.fromTime.getFullYear(),
					model.stat.fromTime.getMonth(), model.stat.fromTime.getDate());
				
				var toDate:Date = new Date(model.stat.toTime.getFullYear(),
					model.stat.toTime.getMonth(), model.stat.toTime.getDate());
				
				while(1 != ObjectUtil.dateCompare(fromDate, toDate))
				{
					nextDate = new Date(fromDate.time + day);
					i = 0;
					total = 0;
					
					for each (var entry:ParaStatVo in model.stat.statRawArr)
					{
						if((-1) != ObjectUtil.dateCompare(entry.statTime, fromDate)
								&& (-1) == ObjectUtil.dateCompare(entry.statTime, nextDate))
						{
							total += entry.ratio;
							i++;
						}
					}
					
					if(0 != i) {
						count ++;
						tempStatVo = new ParaStatVo();
						tempStatVo.dbId = count;
						tempStatVo.ratioStr = (total/i).toFixed(2);
						tempStatVo.statTime = fromDate;
						tempStatVo.statTimeStr = dateFormatter.format(fromDate);
						tempArr.addItem(tempStatVo);
					}
					
					fromDate = nextDate;
				}
			} 
			else if(model.stat.selectedLevel == 1) // level 2 - hour interval
			{ 
				// construct StatShowArr
				var nextHour:Date;
				i = 0;
				total = 0;
				count = 0;
				
				var fromHour:Date = new Date(model.stat.fromTime.getFullYear(),
					model.stat.fromTime.getMonth(), model.stat.fromTime.getDate(),
					model.stat.fromTime.getHours());
				
				var toHour:Date = new Date(model.stat.toTime.getFullYear(),
					model.stat.toTime.getMonth(), model.stat.toTime.getDate(),
					model.stat.toTime.getHours());
				
				while(1 != ObjectUtil.dateCompare(fromHour, toHour))
				{
					nextHour = new Date(fromHour.time + hour);
					i = 0;
					total = 0;
					
					for each (entry in model.stat.statRawArr)
					{
						if((-1) != ObjectUtil.dateCompare(entry.statTime, fromHour)
							&& (-1) == ObjectUtil.dateCompare(entry.statTime, nextHour))
						{
							total += entry.ratio;
							i++;
						}
					}
					
					if(0 != i) {
						count ++;
						tempStatVo = new ParaStatVo();
						tempStatVo.dbId = count;
						tempStatVo.ratioStr = (total/i).toFixed(2);
						tempStatVo.statTime = fromHour;
						tempStatVo.statTimeStr = hourFormatter.format(fromHour);
						tempArr.addItem(tempStatVo);
					}
					
					fromHour = nextHour;
				}
			}
			else // level 3 - 15 min interval
			{ 
				// construct StatShowArr
				var next15Min:Date;
				i = 0;
				total = 0;
				count = 0;
				
				var fromMin:Date = getFloor15Min(model.stat.fromTime);
				var toMin:Date = getFloor15Min(model.stat.toTime);
				
				while(1 != ObjectUtil.dateCompare(fromMin, toMin))
				{
					next15Min = new Date(fromMin.time + fifteenMin);
					i = 0;
					total = 0;
					
					for each (entry in model.stat.statRawArr)
					{
						if((-1) != ObjectUtil.dateCompare(entry.statTime, fromMin)
							&& (-1) == ObjectUtil.dateCompare(entry.statTime, next15Min))
						{
							total += entry.ratio;
							i++;
						}
					}
					
					if(0 != i) {
						count ++;
						tempStatVo = new ParaStatVo();
						tempStatVo.dbId = count;
						tempStatVo.ratioStr = (total/i).toFixed(2);
						tempStatVo.statTime = fromMin;
						tempStatVo.statTimeStr = minFormatter.format(fromMin);
						tempArr.addItem(tempStatVo);
					}
					
					fromMin = next15Min;
				}
			}
			
			model.stat.statShowArr = tempArr;
		}
	
		// convert statRawArr to statPieArr
		public static function getPieStat():void {
			
			var model:AppModelLocator = AppModelLocator.getInstance();
			var notSoHealthy:Number;
			var needAttention:Number;
			
			// get baseline by selected parameter name
			for each(var vo:BaselineVo in model.baseline.baselineItemArr) {
				if(vo.paraName == model.stat.selectedPara) {
				   notSoHealthy = vo.notSoHealthy;
				   needAttention = vo.needAttention;
				}
			}
			
			// construct the pie statistic array
			var i:int = 0;
		    var j:int = 0;
			var k:int = 0;
			var tempVo:PieStatVo;
			
			for each(var svo:ParaStatVo in model.stat.statRawArr) {
			   
			   if(svo.ratio >= 0 && svo.ratio <= notSoHealthy) {
				   i ++;
			   }
			   else if(svo.ratio > notSoHealthy && svo.ratio <= needAttention) {
				   j ++;
			   }
			   else {
				   k++;
			   }
			}
			
			model.stat.statPieArr.removeAll();
			
			// add healthy pie
			tempVo = new PieStatVo();
			tempVo.rangeStr = "Healthy\n(0% - "
				+ notSoHealthy.toString() + "%)";
			tempVo.rate = i;
			tempVo.statusStr = "Healthy";
			model.stat.statPieArr.addItem(tempVo);
			
			// add not so healthy pie
			tempVo = new PieStatVo();
			tempVo.rangeStr = "Not So Healthy\n(" + notSoHealthy.toString() + "% - "
				+ needAttention.toString() + "%)";
			tempVo.rate = j;
			tempVo.statusStr = "Not So Healthy";
			model.stat.statPieArr.addItem(tempVo);
			
			// add need DBA's attention pie
			tempVo = new PieStatVo();
			tempVo.rangeStr = "Need DBA Attention\n(" + needAttention.toString() + "% - "
				+ "100%)";
			tempVo.rate = k;
			tempVo.statusStr = "Need DBA Attention";
			model.stat.statPieArr.addItem(tempVo);
		}
	}
}